package com.xingchen.feima.system.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xingchen.feima.common.base.exception.FeimaException;
import com.xingchen.feima.common.utils.MD5;
import com.xingchen.feima.common.utils.R;
import com.xingchen.feima.common.utils.ResultCode;
import com.xingchen.feima.system.entity.Role;
import com.xingchen.feima.common.entity.User;
import com.xingchen.feima.system.entity.UserRole;
import com.xingchen.feima.system.entity.vo.UpdatePasswordObj;
import com.xingchen.feima.system.entity.vo.UserSearchConditionObj;
import com.xingchen.feima.api.client.OssClient;
import com.xingchen.feima.system.service.RoleService;
import com.xingchen.feima.system.service.UserRoleService;
import com.xingchen.feima.system.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Api(tags = "用户管理")
@RestController
@RequestMapping("/system/user")
public class UserController {

    @Autowired
    private UserService sysUserService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private OssClient ossClient;


    @ApiOperation(value = "获取用户列表")
    @GetMapping("")
    public R getList(){
        List<User> list = sysUserService.list(null);
        return R.ok().data("items", list);
    }

    @ApiOperation(value = "获取分页用户列表")
    @GetMapping("/{currentPage}/{pageSize}")
    public R getPageList(
            @ApiParam(name = "currentPage", value = "a", required = true)
            @PathVariable Long currentPage,
            @ApiParam(name = "pageSize", value = "每页记录数", required = true)
            @PathVariable Long pageSize){

        Page<User> pageObj = new Page<>(currentPage, pageSize);
        sysUserService.page(pageObj, null);

        return  R.ok().data("items", pageObj);
    }

    @ApiOperation(value = "获取条件分页用户列表")
    @PostMapping("/{currentPage}/{pageSize}")
    public R getCondPageList(
            @ApiParam(name = "currentPage", value = "当前页码", required = true)
            @PathVariable Long currentPage,

            @ApiParam(name = "pageSize", value = "每页记录数", required = true)
            @PathVariable Long pageSize,

            @ApiParam(name = "searchCondition", value = "搜索条件对象", required = false)
            @RequestBody UserSearchConditionObj searchCondition){

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        String name = searchCondition.getUsername();
        String begin = searchCondition.getBeginTime();
        String end = searchCondition.getEndTime();

        if (!StringUtils.isEmpty(name)) {
            queryWrapper.like("username", name);
        }
        if (!StringUtils.isEmpty(begin)) {
            queryWrapper.ge("update_time", begin);
        }
        if (!StringUtils.isEmpty(end)) {
            queryWrapper.le("update_time", end);
        }

        Page<User> pageObj = new Page<>(currentPage, pageSize);
        sysUserService.page(pageObj, queryWrapper);

        return  R.ok().data("items", pageObj);
    }

    @ApiOperation(value = "新增用户")
    @PostMapping("")
    public R add(
            @ApiParam(name = "user", value = "用户对象", required = true)
            @RequestBody User user){

        user.setPassword(MD5.encrypt(user.getPassword()));
        sysUserService.save(user);
        return R.ok();
    }

    @ApiOperation(value = "根据ID查询用户")
    @GetMapping("/{id}")
    public R getById(
            @ApiParam(name = "id", value = "用户ID", required = true)
            @PathVariable Long id){

        User user = sysUserService.getById(id);
        return R.ok().data("items", user);
    }

    @ApiOperation(value = "根据ID修改用户")
    @PutMapping("")
    public R updateById(
            @ApiParam(name = "user", value = "用户对象", required = true)
            @RequestBody User user){

        sysUserService.updateById(user);
        return R.ok();
    }

    @ApiOperation(value = "根据ID删除用户")
    @DeleteMapping("/{id}")
    public R removeById(
            @ApiParam(name = "id", value = "用户ID", required = true)
            @PathVariable Long id){

        sysUserService.removeById(id);
        return R.ok();
    }

    @ApiOperation("根据ID列表批量删除用户")
    @DeleteMapping("/batchRemove")
    public R batchRemove(
            @ApiParam(name = "idList", value = "ID列表", required = true)
            @RequestBody List<Long> idList) {

        sysUserService.removeByIds(idList);
        return R.ok();
    }


    @ApiOperation("展示用户已分配角色，需要获取所有角色和已分配角色id列表")
    @GetMapping("/showRole/{userId}")
    public R getMapContainAllRoleListAndAlreadyAssignRoleIdList(
            @ApiParam(name = "userId", value = "用户ID", required = true)
            @PathVariable Long userId) {

        // 获取全部角色列表
        List<Role> allRoleList = roleService.list(null);
        // 根据用户id获取当前用户已分配角色对象列表
        List<UserRole> alreadyAssignUserRoleObjList = userRoleService.list(new QueryWrapper<UserRole>().eq("user_id", userId));
        // 根据当前用户已分配用户角色对象列表获取当前用户已分配角色id列表
        List<Long> alreadyAssignRoleIdList = alreadyAssignUserRoleObjList.stream().map(userRole -> userRole.getRoleId()).collect(Collectors.toList());
        // 将全部角色列表和当前用户已分配角色id列表装到Map中
        Map<String, Object> mapContainAllRoleListAndAlreadyAssignRoleIdList = new HashMap<>();
        mapContainAllRoleListAndAlreadyAssignRoleIdList.put("allRoleList", allRoleList);
        mapContainAllRoleListAndAlreadyAssignRoleIdList.put("alreadyAssignRoleIdList", alreadyAssignRoleIdList);

        return R.ok().data("items", mapContainAllRoleListAndAlreadyAssignRoleIdList);
    }

    @ApiOperation("进行角色分配：根据用户id和已分配角色id列表更新用户的角色")
    @PostMapping("/assignRole/{userId}")
    public R assignRoleByUserIdAndAlreadyAssignRoleIdList(
            @ApiParam(name = "userId", value = "用户ID", required = true)
            @PathVariable Long userId,

            @ApiParam(name = "alreadyAssignRoleIdList", value = "已分配角色id列表", required = true)
            @RequestBody List<Long> alreadyAssignRoleIdList) {

        // 根据用户id删除该用户所有已分配的角色
        userRoleService.remove(new QueryWrapper<UserRole>().eq("user_id", userId));
        // 根据已分配角色id列表生成用户角色对象列表，然后进行批量保存
        List<UserRole> userRoleList = alreadyAssignRoleIdList.stream().map(roleId -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            return userRole;
        }).collect(Collectors.toList());
        userRoleService.saveBatch(userRoleList);

        return R.ok();
    }


    @ApiOperation("修改用户密码")
    @PostMapping("/updatePassword/{userId}")
    public R updatePassword(
            @ApiParam(name = "userId", value = "用户ID", required = true)
            @PathVariable Long userId,

            @ApiParam(name = "updatePasswordObj", value = "修改密码对象", required = true)
            @RequestBody UpdatePasswordObj updatePasswordObj) {
        // 根据用户id查询当前用户信息
        User user = sysUserService.getById(userId);
        // 判断当前用户旧密码是否正确
        if(!MD5.encrypt(updatePasswordObj.getOldPassword()).equals(user.getPassword())) {
            throw new FeimaException(ResultCode.ERROR, "密码错误");
        }
        User userOnlyWithUserIdAndPassword = new User();
        userOnlyWithUserIdAndPassword.setId(userId);
        userOnlyWithUserIdAndPassword.setPassword(MD5.encrypt(updatePasswordObj.getNewPassword()));
        // 如果正确，更新密码
        sysUserService.updateById(userOnlyWithUserIdAndPassword);
        return R.ok();
    }

    // 用户上传头像
    @ApiOperation(value = "用户上传头像")
    @PostMapping("/avatar/{userId}")
    public R uploadAvatar(
            @ApiParam(name = "file", value = "文件", required = true)
            @RequestPart("file") MultipartFile file,

            @ApiParam(name = "userId", value = "用户ID", required = true)
            @PathVariable("userId") Long userId){
        // 远程调用头像上传接口
        Map<String, String> map = ossClient.upload(file);
        // 将返回的url地址保存到数据库
        User user = new User();
        user.setId(userId);
        user.setAvatarUrl(map.get("url"));
        sysUserService.updateById(user);
        return R.ok();
    }
}

